#include <os/task.h>
#include <os/schedule.h>
#include <arch/task.h>
#include <os/pthread.h>
#include <os/process.h>
#include <os/fd.h>

static void AdoptChildToInit(task_t *parent)
{
    task_t *child;
    list_traversal_all_owner_to_next(child, &task_global_list, global_list)
    {
        if (child->parent_pid == parent->pid)
        {
            child->parent_pid = USER_INIT_PROCESS_ID;
        }
    }
}

void SysExit(int status)
{
    task_t *cur = cur_task;
    task_t *parent = NULL;

    InterruptDisable();
    // set exit status
    cur->exit_status = status;
    TaskExitHook(cur);
    // check child process if had zombie process clean them
    ProcessCloseOtherThread(cur);
    ProcessDealZombieChild(cur);
    // adopt child process to init process
    AdoptChildToInit(cur);
    ProcessRelease(cur);

    KPrint("[task] sys exit task %s status %d\n", cur->name, cur->exit_status);

    // check parent process
    parent = TaskFindByPid(cur->parent_pid);
    // parent present
    if (parent)
    {
        // parent process is waitting status
        if (parent->status == TASK_WAITTING)
        {
            InterruptEnable();
            // unblock parent then self into hanging status
            // waitting recover
            TaskUnBlock(parent);
            TaskBlock(TASK_HANGING);
        }
        else
        {
            InterruptEnable();
            // parent no waitting status,set selt to zomble status,waitting parent exit
            TaskBlock(TASK_ZOMBIE);
        }
    }
    else
    {
        InterruptEnable();
        // no parent just exit fileman
        FsFdExit(cur_task);
        // parent process maybe had exit,into zomble status
        // wait init process exit,beacause self had adopt to init process when parent process exit.
        TaskBlock(TASK_ZOMBIE);
    }
}
